using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using System.Collections;
using System.Windows.Forms;
using System.ComponentModel.Design;
using EnvDTE;

namespace XnaDesignerGenerator
{
    public class GameTypeListConverter : TypeListConverter
    {
        public GameTypeListConverter()
            : base(typeof(Microsoft.Xna.Framework.DrawableGameComponent).GetInterfaces())
        {
        }

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            if (sourceType == typeof(string))
                return true;
            return base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
            {
                return Type.GetType(value.ToString());
            }
            return base.ConvertFrom(context, culture, value);
        }

        private void AnalyseCodeElement(CodeElement ce, string ns, IList classes)
        {
            if (ce is CodeNamespace)
                ns += ce.FullName + ".";
            if (ce is CodeClass)
            {
                foreach (CodeElement c in ((CodeClass)ce).Bases)
                {
                    if (c.FullName == "Microsoft.Xna.Framework.Game")
                        classes.Add(Type.GetType(ns + ce.Name));
                }
            }
            if (ce is CodeNamespace && ((CodeNamespace)ce).Members != null)
            {
                foreach (CodeElement c in ((CodeNamespace)ce).Members)
                    AnalyseCodeElement(c, ns, classes);
            }
        }


        public override TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
        {
            IList result = new ArrayList();
            XnaGame component=(XnaGame)context.Instance;
            if (component != null)
            {
                if (component.Project != null)
                {
                    try
                    {
                        foreach (object o in component.Project.ProjectItems)
                        {
                            ProjectItem projectItem = (ProjectItem)o;
                            if (projectItem.FileCodeModel != null)
                            {
                                if (projectItem.FileCodeModel.CodeElements != null)
                                {
                                    foreach (CodeElement ce in projectItem.FileCodeModel.CodeElements)
                                    {
                                        AnalyseCodeElement(ce, "", result);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.Message + "\n" + e.StackTrace, e.GetType().FullName);
                    }
                }
            }
            return new StandardValuesCollection(result);
        }

        public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
        {
            return false;
        }


    }
}
